<template>
  <div class="chart-wrapper">
    <h2 style="font-size: 18px; margin: 10px 0">{{ title }}</h2>
    <div :id="chartId" class="chart" :style="getChartStyle"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'BarChart',
  props: {
    /**
     * 图表标题
     * @example '销售数据分析'
     */
    title: {
      type: String,
      default: '',
    },

    /**
     * X轴分类数据
     * @description 用于显示在X轴上的分类标签
     * @example ['一月', '二月', '三月']
     */
    categories: {
      type: Array,
      required: true,
    },

    /**
     * Y轴数值数据
     * @description 用于显示的实际数据值
     * @example [100, 200, 300]
     */
    values: {
      type: Array,
      required: true,
    },

    /**
     * 数据系列名称
     * @description 用于图例和提示框显示
     * @example '销售额'
     */
    seriesName: {
      type: String,
      default: '',
    },

    /**
     * 图表主题色
     * @description 柱状图的主要颜色
     * @example '#5470c6'
     */
    color: {
      type: String,
      default: '#5470c6',
    },

    /**
     * 图表配置项
     * @description 图表的详细配置，包括提示框、坐标轴等
     */
    chartConfig: {
      type: Object,
      default: () => ({
        height: 200,
        // 提示框配置
        tooltip: {
          show: true,
          trigger: 'axis',
          axisPointer: { type: 'shadow' },
        },
        // 网格配置
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true,
        },
        // X轴配置
        xAxis: {
          show: true,
          axisTick: { alignWithLabel: true },
          axisLabel: {
            color: '#333',
            fontSize: 12,
          },
        },
        // Y轴配置
        yAxis: {
          show: true,
          axisLabel: {
            color: '#333',
            fontSize: 12,
          },
        },
        // 系列配置
        series: {
          barWidth: '60%',
          label: {
            show: false,
            position: 'top',
          },
        },
      }),
    },

    /**
     * PPT导出配置
     * @description PPT导出时的样式和布局配置
     */
    pptConfig: {
      type: Object,
      default: () => ({
        // 图表位置和大小
        position: {
          x: 0.5,
          y: 1.7,
          w: 4.5,
          h: 3.5,
        },
        // 标题配置
        title: {
          x: 0.5,
          y: 1.2,
          fontSize: 16,
          color: '363636',
          bold: true,
        },
        // 图表配置
        chart: {
          showLegend: true,
          legendPos: 'b',
          showTitle: false,
          //数据标签位置
          dataLabelPosition: 'outEnd',
          // 数据标签字体大小
          dataLabelFontSize: 7,
          // 数据标签格式化代码
          dataLabelFormatCode: '',
          //是否显示值
          showValue: true,
          //单位
          unitSuffix: '',
        },
      }),
    },
  },

  data() {
    return {
      // echarts实例
      chart: null,
      // 图表id
      chartId: Math.random().toString(36).substring(2, 15),
    };
  },
  computed: {
    // 图表样式
    getChartStyle() {
      return {
        height: this.chartConfig.height + 'px',
      };
    },
  },
  methods: {
    /**
     * 初始化图表
     * @description 创建echarts实例并首次渲染
     */
    initChart() {
      const chartDom = document.getElementById(this.chartId);
      if (!chartDom) return;
      this.chart = echarts.init(chartDom);
      this.updateChart();
    },

    /**
     * 更新图表数据和配置
     * @description 根据props更新图表的数据和配置项
     */
    updateChart() {
      if (!this.chart) return;

      const option = {
        tooltip: this.chartConfig.tooltip,
        grid: this.chartConfig.grid,
        legend: {
          show: this.chartConfig.legend && this.chartConfig.legend.show != null ? this.chartConfig.legend.show : true,
          data: [this.seriesName],
          itemStyle: {
            color: (this.chartConfig.legend && this.chartConfig.legend.itemStyle.color) || '',
          },
        },
        xAxis: {
          ...this.chartConfig.xAxis,
          type: this.chartConfig.xAxis.type || 'category',
          data: this.categories,
        },
        yAxis: {
          ...this.chartConfig.yAxis,
          type: this.chartConfig.yAxis.type || 'value',
          data: this.categories,
        },
        series: [
          {
            name: this.seriesName,
            type: 'bar',
            data: this.values,
            itemStyle: this.chartConfig.series.itemStyle || { color: this.color },
            barWidth: this.chartConfig.series.barWidth,
            label: this.chartConfig.series.label,
          },
        ],
      };
      this.chart.setOption(option);
    },

    /**
     * 导出为PPT
     * @description 将图表导出为PPT格式
     * @param {Object} pptx pptxgen实例
     * @param {Object} slide 当前幻灯片实例
     */
    exportToPPT(pptx, slide) {
      // 添加图表标题
      slide.addText(this.title, {
        x: this.pptConfig.title.x,
        y: this.pptConfig.title.y,
        fontSize: this.pptConfig.title.fontSize,
        color: this.pptConfig.title.color,
        bold: this.pptConfig.title.bold,
      });
      // 添加柱状图
      slide.addChart(
        pptx.ChartType.bar,
        [
          {
            name: this.seriesName,
            labels: this.categories,
            values: this.values,
          },
        ],
        {
          x: this.pptConfig.position.x,
          y: this.pptConfig.position.y,
          w: this.pptConfig.position.w,
          h: this.pptConfig.position.h,
          //条形方向
          barDir: this.pptConfig.chart.barDir || 'col',
          // 分类轴字体大小
          catAxisLabelFontSize: this.pptConfig.chart.catAxisLabelFontSize || 8,
          //图例方向
          legendPos: this.pptConfig.chart.legendPos,
          // 柱状图颜色正数蓝色，负数红色
          chartColors: this.pptConfig.chart.showLegend ? [this.color.replace('#', '')] : this.values.map(value => (value >= 0 ? this.color.replace('#', '') : 'ee6666')),
          showLegend: this.pptConfig.chart.showLegend,
          showTitle: this.pptConfig.chart.showTitle,
          // 显示值
          showValue: this.pptConfig.chart.showValue,
          // 显示数据表
          // showDataTable: true,
          // 数值轴刻度步长
          valAxisMajorUnit: this.pptConfig.chart.valAxisMajorUnit,
          // 数据标签位置
          dataLabelPosition: this.pptConfig.chart.dataLabelPosition,
          // 分类轴标签位置
          catAxisLabelPos: 'low',
          // 条形间距
          barGapWidthPct: this.pptConfig.chart.barGapWidthPct || 50,
          // 数据标签格式化代码
          dataLabelFormatCode: this.pptConfig.chart.dataLabelFormatCode,
          // 数据标签字体大小
          dataLabelFontSize: this.pptConfig.chart.dataLabelFontSize,
        }
      );
    },
  },

  watch: {
    /**
     * 监听数据变化
     * @description 当数据变化时自动更新图表
     */
    values: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
    categories: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
    chartConfig: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
  },

  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });
  },

  beforeDestroy() {
    this.chart && this.chart.dispose();
    this.chart = null;
  },
};
</script>

<style lang="less" scoped>
.chart-wrapper {
  text-align: center;
  .chart {
    width: 100%;
  }
}
</style>
